home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-11-07 | 28.0 KB | 702 lines | [TEXT/EDIT] |
- September 11, 1989
-
- WINDOID #9 (Part 2)
-
- A Publication for the Informed HyperCard User and the Newsletter for the Apple
- HyperCard User Group
-
- EDITOR: DAVID LEFFLER
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- IN THIS ISSUE:
- Part 1
- • Editor's Corner
- • HyperCard User Tips
- • Corrupted Stacks
- • ChangeFont
- • Stack Evaluation Guidelines
- Part 2
- • Command Synthesis Exotica
- • HyperEducation
- • Message History
- • Internationalizable StackWare
- • HyperCard Novice Corner
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- COMMAND SYNTHESIS AND OTHER HYPERTALK EXOTICA
-
- By Hunt Stoddard
-
- Few realize that by employing a few simple scripting "tricks," one can fully
- exploit the expressive power of HyperTalk and accomplish feats that are
- otherwise impossible. Command synthesis is prime among these.
- Using command synthesis, a scriptor first "synthesizes" a HyperTalk command (or
- function), then executes it with the "Do" command. This description is
- deceptively simple and does not reveal the great things you can do with this
- technique. For example, imagine you’ve got a stack with a variable number of
- background fields, and you want to transfer the contents of these fields into
- similarly numbered fields in another stack. Your first reaction may be to set
- up some code to iterate through the "number of fields," transferring field
- contents one-by-one. But there is a much better way to do this. The following
- script simply iterates through the fields, synthesizing "Put" commands and
- loading the field values into temporary variables. Next, we transfer to the
- second stack and reverse the process, synthesizing "Put" commands to load the
- corresponding fields:
-
- on mouseUp --simple command synthesis.
- repeat with i = 1 to the number of fields
- fields
- --synthesize the put command:
- put "put field" && i && "into var" & i into command
- do command --and execute it
- end repeat
- lock screen
- push card
- go stack "Another Stack" --transfer to
- --the second stack
- repeat with i = 1 to the number of fields
- --the reverse put command:
- put "put var" & i && "into field" && i into command
- do command
- end repeat
- pop card
- unlock screen
- end mouseUp
-
- The same script can be improved to handle the case where the two sets of fields
- are named similarly, but not necessarily numbered the same. In this case, we
- save the field names in a separate container called fieldNames. In the second
- stack, we use these names to designate the correct field to load:
-
- on mouseUp --named, unordered fields.
- put empty into fieldNames
- repeat with i = 1 to the number of fields
- put "put field" && i && "into var" & i into command
- put the short name of field i into line i of fieldNames
- do command
- end repeat
- lock screen
- push card
- go stack "Another Stack"
- repeat with i = 1 to the number of fields
- put "put var" & i && "into field line i of fieldNames" into command
- do command
- end repeat
- pop card
- unlock screen
- end mouseUp
-
- The next stop on our exotic tour is an example of handlers passed as
- parameters. This example also employs command synthesis. The mouseUp handler
- below might appear in a button script, whereas the last three handlers would
- appear in the card, background, stack, or Home stack scripts. When the button
- is pressed, the askQuestion function is passed the name of either the
- affirmDefault function, or the denyDefault function. Depending on which
- function handler is passed, an answer box is displayed with either the "OK" or
- "Cancel" buttons as default. This is admittedly a rather whimpy example and
- does not do justice to the practical uses of passing functions and handlers as
- parameters.
-
- on mouseUp --handlers/Functions as
- --parameters
- if askQuestion ("Launchnow?","affirmDefault")
- then answer "You said 'OK'"
- else answer "You said 'Cancel'"
- end mouseUp
-
- function askQuestion theQuestion, whichFunction
- do "get" && whichFunction && "(theQuestion)"
- return it
- end askQuestion
-
- function affirmDefault question
- answer question with "CANCEL" or "OK"
- return it is "OK"
- end affirmDefault
-
- function denyDefault question
- answer question with "OK" or "CANCEL"
- if it is "OK" then return true else return false
- end denyDefault
-
- The next example was spurred by my desire to surmount HyperCard’s recursion
- error checking. HyperCard is wary of recursion and flags an error if too much
- of it happens. This example involves the recursive creation of objects. In
- traditional object-oriented programming, objects are programming entities. Why
- not use HyperCard’s objects as programming entities as well? Make a button
- called "Factorial" and insert the first script below. Then make another button
- called "Do It" and insert the mouseUp handler below. Press "Do It." "Do It"
- calls factorial, which clones itself successively and calculates the factorial
- of a number. In the process, it eventually kills all its clones and passes a
- value back in returnValue. As it turns out, this way of calculating the
- factorial is about a zillion times slower and messier than doing a direct
- recursive call in HyperCard 1.2; so you can make of it what you will.
-
- on factorial number --script of btn "Factorial"
- global returnValue
- if number < 0 then
- put zero into returnValue
- exit factorial
- end if
- if number is zero or number is one then
- put 1 into returnValue
- exit factorial
- end if
- get the loc of me
- add 20 to item 1 of it
- add 20 to item 2 of it
- doMenu "New Button"
- set the script of btn (the number of btns) to the script of me
- set the loc of btn (the number of btns) to it
- set the name of btn (the number of btns) to "Factorial" && number
- send "factorial" && number-1 to btn (the number of btns)
- select btn (the number of btns)
- doMenu "Clear Button"
- choose browse tool
- multiply returnValue by number
- end factorial
-
- on mouseUp --script of btn "Do It"
- global returnValue
- ask "Calculate the factorial of what?"
- if it is empty then exit mouseUp
- send "factorial" && it to btn "Factorial"
- answer returnValue
- end mouseUp
-
- Next on the list of exotica is a method of passing the "name" of a field to a
- handler and letting it reference the field. This increases flexibility. For
- instance, the handler below will clear out any empty lines from a field. To
- use it, however, you must call it with the format:
-
- clearEmptyLines the name of field "one"
-
- or
-
- clearEmptyLines the name of card field id 3345 etc.
-
- Notice that you can easily switch between card and background fields.
-
- on clearEmptyLines fieldName
- put "put" && fieldName && "into theLines" into command
- do command
- repeat with k = (the number of lines of theLines) down to 1
- if word 1 of line k of theLines is empty
- then delete line k of theLines
- end repeat
- put "put theLines into" && fieldName into command
- do command
- end clearEmptyLines
-
- Last and least, you can intercept command messages and alter their parameters
- if you simply read the parameters, alter them, and reissue the command. For
- example, this answer handler will capitalize any answer string you use:
-
- on answer
- get param(1)
- repeat with k = 1 to the number of chars in it
- if chartonum(char k of it) > 91
- then put numtochar(chartonum(char k of it)-32) into char k of it
- end repeat
- send "answer it" to HyperCard
- end answer
-
- I do hope that some of these "unusual" techniques will find a place, if not in
- your heart, then in your scripts. The easy solutions are not always
- straightforward.
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- HYPEREDUCATION
-
- By Patricia M. Horton, ETC Associates
-
- Welcome! In keeping with the spirit of HyperCard and WINDOID, this column both
- shares HyperCard education news and provides a forum for academically-oriented
- AHUG members.
-
- University of Illinois, Urbana-Champaign, Sociology Department Professor Robert
- Alun Jones has reported on a Hypermedia Learning Laboratory. Opened January
- 1989, twelve networked Mac IIs run HyperCard and support CD-ROM with
- interactive video to serve students and faculty. Simultaneously—in the
- University’s residence halls—clusters of Mac SEs run HyperCard. As these
- locales mirror each other, projects begun in one environment can be continued
- at the other location. Within a year it is hoped the environments will be
- linked via a campus-wide network.
-
- In the past three years, Professor Jones investigated hypermedia, increased
- contacts with the Macintosh community of educators and developed materials for
- a course titled "The Social Bond." Active student participation fosters
- continued development of materials and stacks. By clicking a "Notes" tab,
- students comment directly about stacks, ask questions, and receive answers from
- instructors, teaching assistants, or fellow students. Instead of a written exam
- and term paper, course requirements include creation of materials. Students
- cooperate in educating themselves, one another, and future users of these
- accumulating course materials.
-
- A HyperCard Workshop now meets weekly for Illini students, faculty, and
- administrators to share stack building information and critical comments. A
- Hypermedia Projects Group meets monthly so that people from a variety of campus
- units can be made aware of ongoing as well as possible applications. The
- education topics arecontained in the November issue of Academic Computing
- available from:
- P.O.Box 804, McKinney, TX 75069
-
- Professor Robert Alun Jones can be contacted through AppleLink: A0314.
- Questions and comments about HyperEducation may be directed to
- Patricia M. Horton @ AHUG.
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- MESSAGE HISTORY
-
- by Will Johnston, Steve Russ,
- and Kevin Calhoun
-
- Here are a couple of lines of HyperTalk you can place in the script of your
- Home stack in order to enhance the message box. There are four handlers, one
- each for returnKey, arrowKey, clearMsgHistory, and tabKey.
-
- The returnKey handler maintains a list of the messages you send from the
- message box.
-
- The arrowKey handler recalls one of your stored messages and puts it into the
- message box, cycling backwards through the list if the up arrow is pressed and
- forwards if the down arrow is pressed. The message list is a "circular
- buffer"; in other words, it wraps around as you cycle through the stored
- messages.
-
- The clearMsgHistory handler clears the list of stored messages.
-
- The tabKey handler does nothing but call clearMsgHistory—you can change this
- handler so that the message list is wiped out whenever you prefer.
-
- on returnKey
-
- -- The user has sent a new message from the
- -- message box by pressing the return key.
- -- We intercept the message here and store
- -- it in a global list, unless we have it stored there already.
-
- global msgCount,msgHistory,whichMessage
-
- -- msgCount = the number of stored messages in our global list
- -- msgHistory = our global list of stored
- -- messages, 1 per line
- -- whichMessage = the number of the message now showing in the message box
-
- put msg into thisMessage
-
- -- do we have this message already in our global list?
-
- get offset(thisMessage,msgHistory)
-
- if it is 0 then -- we didn’t have this one already
- add one to msgCount
- put thisMessage & return after msgHistory
- put msgCount into whichMessage
- end if
-
- pass returnKey
-
- -- This is vital. If we don’t pass returnKey, the message won’t
- -- be sent any further up the hierarchy, and whatever the user
- -- wanted to happen won’t happen!
-
- end returnKey
-
- on arrowKey direction
-
- -- The user wants to put one of the messages we’ve stored in
- -- our global list into the message box.
-
- global msgCount,msgHistory,whichMessage
-
- -- msgCount = the number of stored messages in our global list
- -- msgHistory = our global list of stored messages, 1 per line
- -- whichMessage = the number of the message to be shown in the message box.
-
- if direction is "up" then
-
- -- show the message prior to the current one
-
- subtract one from whichMessage
- if whichMessage is 0 then put msgCount into whichMessage
-
- -- "wrap around" from first to last message
-
- end if
-
- if direction is "down" then
-
- -- show the message that followed the current one
- add 1 to whichMessage
- if whichMessage > msgCount then put 1 into whichMessage
- -- "wrap around" from last to first message
- end if
-
- if direction is "left" or direction is "right" then pass arrowKey
- else put line whichMessage of msgHistory
-
- end arrowKey
-
- on clearMsgHistory
-
- -- forget everything about the message history
-
- global msgCount,msgHistory,whichMessage
- put 0 into msgCount
- put empty into msgHistory
- put 0 into whichMessage
- end clearMsgHistory
-
- on tabKey
- clearMsgHistory
- pass tabKey
- end tabKey
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- WRITING INTERNATIONAL STACKWARE
-
- Written by Hans Peter Brøndmo, Apple Japan
- Modified by Susan Razura, International Engineering
-
-
- This document discusses some important issues that you should keep in mind if
- you want your stackware to be localizable. To localize stackware means to
- translate it from its "native" language to some other language and script
- system. This document is intended as a combination of common-sense suggestions
- as well as technical information and hints.
-
- It is assumed that you have a basic familiarity with the main HyperCard
- concepts and terminology when reading this document.
-
- When you start planning and designing a new stack, whether it be for your
- personal use, shareware or as a commercial product, it is important that you
- follow the guidelines outlined in this document. The "rules" you follow to
- make it simpler to localize your stackware will also bring other benefits.
- First of all, it will make it easier to maintain your stacks. Therefore, if at
- some later date you want to modify your stack or add a new feature, your job
- will be easier. Secondly, you’ll ensure that your stackware will have a place
- in international markets. And you will afford an opportunity for the
- translated stack to be just as robust as your original version.
-
- As a rule of thumb, one might say that there are two types of stackware as far
- as international is concerned. Firstly, you have stacks that could be run on
- any language system without script localization. Such a stack might, for
- example, be your Address Stack. It should work with little or no changes,
- whatever language system your Macintosh is operating with. The second type of
- stack is one that needs to be localized in order to work at all. More advanced
- stackware with complex scripts would normally fall into the second category.
- The issues discussed in this document are relevant to developers of stackware
- in both categories.
- The Guidelines
-
- The list below summarizes the guidelines; the following sections explain them
- more fully.
-
- 1. Plan text layout carefully.
- 2. Place text in fields and avoid paint text.
- 3. Avoid text embedded in your scripts / XFCNs.
- 4. Document scripts, algorithms and any hidden objects.
- 5. Don’t make assumptions about formats.
- 6. Use English in your scripts as much as possible.
- 7. Try using culturally independent graphics, symbols and icons.
-
- Plan Text Layout carefully
-
- The amount of text required to express identical content across language
- boundaries varies. Text needs room to grow: up, down and sideways. Keep in
- mind that characters with diacriticals are widely used outside of the U.S. and
- that such characters may extend up to the font ascent line. Some system fonts
- contain characters which extend to both ascent and descent lines. Likewise,
- the size of certain non-Roman fonts is generally more complex and therefore
- often needs to be larger than it’s Roman counterparts. For example, some
- non-Roman fonts are not legible on the screen at 9 point.
-
- You should, therefore, think carefully about your layout when planning where
- and how much text to place on a card.
-
- There are two basic ways to put text on a Card. You can "draw" the text on the
- card making it a bitmap, or you can place the text in a field. Since you can
- achieve certain special effects such as stretching, distorting and simple
- animation by placing text directly on the card as a bitmap image, there are
- situations where it will be the right thing to do.
-
- Normally, though, if all you want is simple text on a screen, you should place
- it in a text field. Placing text in a Text Field has two immediate advantages.
- Firstly, it greatly simplifies localizing and changing the text. Secondly, you
- will normally save space by placing text in a field as opposed to making it
- picture. Furthermore, it is obviously not possible to search for text which is
- not in a text field, nor is it possible to read it in any other way.
-
- If you are using bitmapped text, try to use a font that supports the full
- Macintosh character set, and make the font available to those who will be
- translating.
-
- Button text
-
- If you set the Show Name property of a button to true, note that the name of
- the button will change in the localization process. Furthermore, if you
- reference that button in a script by calling it by name, this will have to be
- localized as well. (See the next section on "text embedded in your scripts.")
- It would be better to reference the button by its ID. Another possiblity would
- be to turn off the Show Name property and create a transparent field over the
- button to display the name.
-
- Avoid text embedded in your scripts
-
- The Macintosh supports "resources" as a way of separating certain types of data
- from an application. In other words, data such as strings that belong to the
- application do not need to be embedded in the code, indeed they should not be
- embedded. This greatly simplifies the software localization process.
- HyperCard stacks can also contain resources. For example, sound is stored as a
- resource in HyperCard or the stack.
-
- Text strings in a HyperCard script are included in the scripts themselves,
- causing potential problems for localization. There are some possible
- workarounds for this problem. One solution could be to place all strings in an
- invisible text field and to simply index into the field to get the strings.
- Another option would be to save the strings in resources and extend HyperTalk
- so it can access the strings. Finally, if you choose not to incorporate one of
- the above solutions, you can still simplify the localization effort immensely
- by making a note of where such text resides in your stacks. It could be just a
- simple comment in the beginning of your script such as
-
- -- All text to be translated can be found on lines ending with "-- ***".
-
- This way the translator need only search for the specified pattern to find all
- instances of text that need to be translated.
-
- Document your scripts, algorithms and any hidden objects
-
- It cannot be emphasized strongly enough how important it is that you document
- your work. Some people plan and design carefully before writing an
- application, others are of a more impulsive nature, writing their scripts based
- on an idea that they have not clearly formulated when starting. Which ever
- category you belong to, it is crucial to the success of your project that you
- document and comment as you go along.
-
- The first basic type of documentation is in scripts that contain in-line text.
- Comment as you write your scripts and update the comments as you make changes.
- The second type of documentation applies to high-level descriptions. For
- complex message handlers of an object, you should include a description of your
- object and of the algorithms you are using, if any. Furthermore you may find
- it very useful to note where you are implementing message handlers (i.e., what
- objects implement the methods for what messages). You should also discuss
- "global dependencies" that are important for your script to work properly. A
- breakdown of the control structure would also be helpful.
-
- Equally rigorous rules for documentation naturally apply to XCMDs. The source
- code for an XCMD should be documented carefully in line with normal coding
- practice. Furthermore, your stackware documentation should contain a section
- outlining what XCMDs are used. Specifically, it is important to think about
- and document how your XCMDs might be affected by international issues. Such
- issues might be related to printing, date and time formats or script manager
- compatibility.
-
- NOTE! You probably should not rely on going back to comment your work after
- you finish scripting. It is inevitable that as time passes, you will forget
- the specifics of the implementation of an algorithm or trick in your HyperTalk
- script. Write comments as you write scripts, and update them when you make
- modifications.
-
- Don’t make assumptions about formats
-
- Dates
- HyperCard supports a variety of date formats. But it is up to the HyperTalk
- script writer to ensure that his or her script will work regardless of the date
- format of the system that is currently being used. For example, the date
- format for the short date in HyperTalk is "88.06.01" in Japanese, "01.06.88" in
- English, and "06.01.88" in Norwegian. The long date is equally different. So
- your script ought to take these varying formats into account. Perhaps the best
- way to ensure cross-language compatibility is to use the HyperTalk DateItems
- function. DateItems gives you a set of number items indicating the year (in
- the Roman calendar), month, day, hour, minute, second and day of week. To find
- the name of a month, day, etc., you can do a lookup in a table (e.g., a text
- field). This table should be clearly marked, making it easily localizable.
-
- The International Utilities in the Macintosh Operating System provide support
- for other formats, namely:
-
- Numbers
- The characters which denote the decimal point and thousands separator vary from
- country to country.
-
- Units of Measure
- Currency symbols differ among countries as do the use of metric and SAE
- measurement.
- Sorting and Searching
- Different language systems handle the ordering of characters in different ways.
-
- If you are making any assumptions about formats in your scripts, you should
- clearly indicate where you are doing so and what those assumptions are. This
- way localization is simplified, and it becomes possible to change the scripts
- where needed to make them compatible with different formats.
-
- Likewise, you can write an XFCN that will find out what language system you are
- currently using and deal with formats thereafter.
-
- Power Keys
- You should also be aware that the power keys are localized in the various
- language versions of the HyperCard application. For example, with power keys
- turned on, "r" will perform the revert function in the English version of
- HyperCard, while in the Swedish version, it turns the grid on or off.
-
- Grammar
- The rules for punctuation and word order are not the same for all languages.
- Allow for flexibility in this context.
-
- Use as much English as possible in your scripts
-
- The previous section on "avoiding embedded text in scripts" discusses a couple
- of possible solutions for how to avoid placing text "in-line" in HyperTalk
- scripts. Likewise, you should try to avoid placing non- English arguments in
- your scripts as well. In particular, this relates to the HyperTalk "doMenu"
- command. The command
-
- <doMenu menuItemName>
-
- should always use the English menuItemName. All versions of HyperCard will
- work with the English name of a menu item as the argument to doMenu, while only
- the localized version will work with the "translated" name of a menu item.
- Therefore, by using the English name, you will ensure that your doMenu command
- will always work correctly, regardless of the language version of HyperCard.
-
- Use Culturally Neutral Graphics and Symbols
-
- To further aid localization and cross-cultural translations, you should think
- carefully about the symbolism and graphics that you use in your stacks. There
- are two main concerns that you might want to keep in mind. One is that symbols
- that have a clear and unambiguous meaning in your own culture might not be
- known in another. The other is that specific nationalistic or patriotic
- imagery and symbolism might confuse or even offend people from other countries.
-
- Some examples of items that differ around the world…
-
- • Holidays.
- • Religious practices.
- • Address formats, including "ZIP" codes and phone numbers.
- • Telephones and mailboxes.
- • Mortgage and interest calculations.
- • Communications, data transmission and reception.
- • Keyboard layouts and character sets.
- • Paper sizes.
- • Text data compaction and encoding must allow character codes from $20 to $FF
- • Bikini-clad women and champagne bottles are not acceptable in the Arab world
-
- Such items should be easily modifiable if your stack is to be translated into
- another language. However, keep in mind that there are many small countries
- throughout the world who sell Macintosh computers but do not localize the
- software. Such countries will take the English language version, so you will
- want to make sure that the original design is culturally acceptable. Use
- common sense and try your design out on people that have a different background
- than your own.
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- HYPERCARD NOVICE CORNER
-
- by Phil Wyman
-
- This Novice Corner should be fun and easy for us HyperCard novitiates. We’ll
- put a picture on a button! The hackers call these pictures "icons," so if you
- want to pretend you’re not a novice when you’re at a party or something,
- definitely call it an "icon."
- Choose "New Button" from the Objects menu. (NOVICES NOTE: If you don’t have an
- Objects menu, please read Windoid #7’s Novice Corner that describes in
- mind-wrenching detail how to get the Objects menu to appear.) A new button
- should appear on your screen with marching ants around it. Choose "Button info"
- from the Object menu and click on the button that says "ICON".
-
- Now, you are given a series of pictures that are available to you. Click on one
- of these pictures to select it. Your selected picture should now be highlited.
- Click on the "OK" button.
-
- Now your button will look differently. It will have a picture on it!!! You
- will probably have to reshape your button to see the whole picture. To do this,
- click on a corner of the button and hold the mouse down and pull to make the
- button bigger. Along with seeing your entire picture, you should see the words
- "New Button" below the picture, which is the actual name of the button. Let’s
- change that name.
-
- Choose "Button info" from the Objects menu. On the ensuing window, which is
- called a "modal dialog box" by non-novices, type in your new name. The new name
- should go directly into the top of the window. Click the OK button.
-
- Now when you look at your button, you should have a new name below your
- picture.
-
- Let’s try to reposition the button to a different place on the screen. The
- trick is to point to the center of the button with the mouse, then hold down
- the mouse button, and move the mouse around. Try it!
-
- If you’ve gotten this far, have a JOLT cola and a twinkie, and stay up all
- night with HyperCard.
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- If you would like information about AHUG, write to:
-
- Apple HyperCard User Group
- MS/27-AHUG
- 20525 Mariani Ave.
- Cupertino, CA 95014
- Our AppleLink is: UG.AHUG
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- THE FORM
-
- If you have a bug, suggestion, comment, or just want to know the best way to do
- something in HyperCard, you can fill out the form below and send it to:
-
- AHUG c/o David Leffler
- Apple Computer, Inc.
- MS / 22-Q
- 20525 Mariani Ave.
- Cupertino, CA 95014
-
- Or copy the format and
- AppleLink(TM) it to:
- HYPERBUG$
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- TELL HYPERCARD
- You can use this form to notify the HyperCard team of problems, bugs, and
- enhancement requests.
-
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
- THE FORM:
-
- Please use the following form to make a difference in the world:
-
- Date:
- Name:
- Address:
- Phone #:
- Versions of:
- a. HyperCard:
- b. Associated software:
- c. System Software:
- 1. System
- 2. Finder
- 3. ImageWriter file
- 4. LaserWriter file
- 5. Any others
- Type of Macintosh:
- Peripherals:
- Description of problem, suggestions or comments:
-
-
- If you have some information for us please fill this form out as completely as
- possible and send it to us. You will be glad you did!
-
-
-
-